/*
Copyright 2010,2011 Matt Van Der Westhuizen

This file is part of CGLL.

CGLL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

CGLL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with CGLL.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.chaoticengine.cgll.factory;

import org.chaoticengine.cgll.exceptions.LoadingException;
import java.io.InputStream;
import org.chaoticengine.cgll.entity.Entity;
import org.chaoticengine.cgll.entity.component.move.SimpleMovementComponent;
import org.chaoticengine.cgll.entity.component.effects.ParticleEffectComponent;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.geom.Vector2f;
import org.simpleframework.xml.Serializer;

/**
 * This singleton class is responsible for loading special effect definitions
 * and instantiating instance of those special effects on request.
 *
 * @author Matt v.d. Westhuizen
 */
public class EffectFactory extends AbstractFactory {
    // Members
    private static EffectFactory instance = null;
    private GameContainer gc = null;
    private Serializer srl = null;

    private EffectFactory() {}

    public static EffectFactory getInstance() {
        if (instance == null) {
            instance = new EffectFactory();
        }

        return(instance);
    }

    public Entity getEntity(String name) throws LoadingException {
        InputStream is = getCachedResource("data/effects/entity/" + name + ".xml");
        Entity result = null;
        try {
            result = srl.read(Entity.class, is);
        } catch (Exception ex) {
            throw new LoadingException(ex);
        }

        return(result);
    }

    /**
     * Create an effect that will replace an existing entity, assuming it's position
     * and movement parameters.
     *
     * @param name Name of the effect to load.
     * @param e The entity whose position and motion to emulate.
     * @return The effect entity.
     * @throws LoadingException Thrown if there are problems loading the effect.
     */
    public Entity getEntity(String name, Entity e) throws LoadingException {
        Entity result = getEntity(name);

        result.setPosition(e.getPosition());
        result.setBounds(e.getBounds());

        // Add a movement component
        Vector2f ev = e.getComponentManager().getVelocity();
        SimpleMovementComponent compMove = new SimpleMovementComponent();
        compMove.setAcceleration(ev.length());
        result.getComponentManager().addComponent(compMove);

        return(result);
    }

    /**
     * Create an effect component that can be added to an existing entity.
     *
     * @param name Name of the effect to load.
     * @param e The entity whose position and motion to emulate.
     * @return The effect entity.
     * @throws LoadingException Thrown if there are problems loading the effect.
     */
    public ParticleEffectComponent getComponent(String name) throws LoadingException {
        InputStream is = getCachedResource("data/effects/component/" + name + ".xml");
        ParticleEffectComponent result = null;
        try {
            result = srl.read(ParticleEffectComponent.class, is);
        } catch (Exception ex) {
            throw new LoadingException(ex);
        }

        return(result);
    }

    public GameContainer getGameContainer() {
        return gc;
    }

    public void setGameContainer(GameContainer gc) {
        this.gc = gc;
    }

    public Serializer getSerializer() {
        return srl;
    }

    public void setSerializer(Serializer srl) {
        this.srl = srl;
    }
}
